import os
import json
from pymdi import pymdi
import requests
import re
import yaml
from pybagmining.pybagmining import Client as pyBagMiningClient
import os
import rosbag
import hashlib
import random
import string
import sys
from colorama import Fore

# https://cdi-web.cla-dev.mmtdev.com/cdi/token
# 先获取自己的token, 点击下 reset
token_self_ = "dcdad927-a278-4fad-95ea-f3e8f0c1cca7"
json_ = {}

# 1. input bag md5


def get_bag_info_md5(mdc5):
    client = pymdi.Client(token=token_self_)
    md5_list = [mdc5]
    result = client.get_meta(md5_list)
    if len(result) == 0:
        return
    # 区分dfdi 还是cfdi
    fdi_type = client.get_meta(md5_list)[0]["asset"]["fdi_type"]
    if fdi_type == "CFDI":
        try:
            json_["bag_name"] = client.get_meta(md5_list)[0]["name"]
            json_["bag_md5"] = mdc5
            json_["business_type"] = client.get_meta(
                md5_list)[0]["custom_meta"]["project_name"]
            json_["car_type"] = client.get_meta(
                md5_list)[0]["custom_meta"]["car_type"]
            deploy = client.get_meta(
                md5_list)[0]["custom_meta"]["mass_production"]["system_name"]
            json_["car_plate"] = client.get_meta(
                md5_list)[0]["custom_meta"]["mass_production"]["vin"]
            get_bag_info_deploy(deploy, 0)
        except:
            return
    else:
        # 异常处理
        try:
            json_["business_type"] = client.get_meta(
                md5_list)[0]["fdi"]["fmp"]["car_info"]["business_type"]
            json_["car_type"] = client.get_meta(
                md5_list)[0]["fdi"]["fmp"]["car_info"]["car_type"]
            json_["car_plate"] = client.get_meta(
                md5_list)[0]["fdi"]["fmp"]["car_info"]["car_plate"]

            modules = client.get_meta(
                md5_list)[0]["fdi"]["soft_version_v2"]["modules_version"]
            for module in modules:
                if "vehicle_service" in module["name"]:
                    json_["branch"] = module["branch"]
                    json_["commit"] = module["commit"]
                    json_["name"] = module["name"]

            parse_metas = client.parse_meta(md5_list)
            json_["bag_name"] = parse_metas[0]["bag_name"]
            json_["bag_md5"] = mdc5

            deploy = client.get_meta(
                md5_list)[0]["fdi"]["soft_version_v2"]["packages_version"][0]["version"]
            get_bag_info_deploy(deploy, 1)
        except:
            return
# input 为deploy


def get_bag_info_deploy(deploy, flag=0):
    payload = {'package_name': deploy}
    response = requests.get(
        'https://ep.momenta.works/backend/package-meta/api/v1/metas', params=payload)
    # print(response.json())
    res_json = response.json()
    # print("res_json:", res_json)
    # print("res_text:", response.text)
    if (res_json["status"] == 20002):
        json_["status"] = 0
        return
    try:
        for array in res_json["data"]["meta"]:
            if "version_file_url" == array["key"]:
                resp = requests.get(array["value"])
                # print("json", resp.json())
                json_["mf_system_branch"] = resp.json()["branch"]
                json_["mf_system_commit_id"] = resp.json()["commit_id"]
                json_["deploy"] = deploy
        if flag == 0:
            for array in res_json["data"]["meta"]:
                if "reproduction_yaml_file_url" == array["key"]:
                    # print(array["value"])
                    resp = requests.get(array["value"])
                    data = yaml.safe_load(resp.content)
                    # print("data", data)
                    for module in data["modules"]:
                        # print("modules:", module["name"])
                        if "vehicle_service" in module["name"]:
                            # print("modules_vehicle_service:", module["name"])
                            json_["branch"] = module["git_branch_old"]
                            json_["commit"] = module["git_commit"]
                            json_["name"] = module["name"]
                if "project_name" == array["key"]:
                    json_["business_type"] = array["value"]
        json_["status"] = 1
    except:
        return

# input 为bagfile


def get_bag_info_bagfile(bagfile):
    body = {
        "query": {
            "bool": {
                "must": [
                    {
                        "name": bagfile
                    }
                ],
                "must_not": []
            }
        },
        "sort": "create_time:desc",
        "meta_type": "bag",
        "limit": 10000
    }
    resp = requests.post("https://data.momenta.works/api/v2/search/meta",
                         headers={"Authorization": token_self_}, json=body)
    if (resp.json()["total"] == 0):
        return
    resp_md5 = resp.json()["data"][0]
    get_bag_info_md5(resp_md5)


def get_input(input):
    pattern_md5 = r'^[a-f0-9]{32}$'
    pattern_bagfile = r'.*\.bag$'
    pattern_tgzfile = r'.*\.tgz$'
    #  清空json
    json_.clear()

    if re.match(pattern_md5, input):
        get_bag_info_md5(input)
        print('This is an md5 hash value.')
    elif re.match(pattern_bagfile, input):
        get_bag_info_bagfile(input)
        print('This is a .bag file name.')
    elif re.match(pattern_tgzfile, input):
        get_bag_info_deploy(input)
        print('This is a .tgz file name.')
    else:
        print('Unrecognized input.')
        json_["status"] = 0


def get_info_json():
    return json_


# https://momenta.feishu.cn/wiki/wikcnw7czrHBlWdO4H9Cwzmxj7c?table=tblc77apYQ1oPG3J&view=vewP2B92zv
# https://momenta.feishu.cn/wiki/wikcn00LiJcFLaawHBVSILrwxKb?table=tblu8Puq8gohc5ep&view=vewUIIwxDi
mining_client = pyBagMiningClient(token=token_self_)
topic_message_list = list()  # 存储topic中数据的列表

# 在线获取bag里面的消息
def get_bag_messages(required_topic_set, bag_md5):
    # clear topic_message_list
    topic_message_list.clear()
    bag = mining_client.get_ros_bag_info(bag_md5)
    for topic, msg, t in bag.read_messages(list(required_topic_set)):
        topic_message_list.append(
            {"recv_time": t, "topic": topic, "message": msg})
    return topic_message_list

# 在线下载bag里面的消息到指定文件
def download_rosbag_messages(required_topic_set, bag_md5, download_file):
    # 生成一个长度为10的随机字符串
    random_string = ''.join(random.choices(string.ascii_letters + string.digits, k=10))
    temp_rosbag = download_file + random_string + ".temp"
    with rosbag.Bag(temp_rosbag, 'w') as outbag:
        bag = mining_client.get_ros_bag_info(bag_md5)
        total_duration = bag.get_end_time() - bag.get_start_time()
        for topic, msg, t in bag.read_messages(list(required_topic_set)):
            try:
                if topic in required_topic_set:
                    outbag.write(topic, msg, t)
            except UnicodeDecodeError:  # 如果发生 UnicodeDecodeError 则执行以下操作
                print(f"Encountered a UnicodeDecodeError at {topic}, but continuing...")
                continue  # 跳过当前循环，进入下一次循环
            progress = max(0, (t.to_sec() - bag.get_start_time()) / total_duration)
            # Calculate the number of dots and spaces for the progress bar
            dots = "." * int(progress * 50)
            spaces = " " * (50 - len(dots))
            # Generate the progress string
            progress_str = f"[{dots}{spaces}] {t.to_sec()} / {bag.get_end_time()}"
            # Print the progress with carriage return at the end, so it overwrites the current line
            sys.stdout.write(f"\r{Fore.GREEN}{progress * 100:.2f}% {progress_str}")
            sys.stdout.flush()
        print("\r\n")
        os.rename(temp_rosbag, download_file)
